package com.bird.framework.config;

import com.bird.common.annotation.EnumDescription;
import com.bird.system.domain.entity.SysDictDataEntity;
import com.bird.system.domain.entity.SysDictTypeEntity;
import com.bird.system.domain.params.SysDictDataQueryParams;
import com.bird.system.domain.params.SysDictTypeQueryParams;
import com.bird.system.enums.BaseEnum;
import com.bird.system.service.ISysDictDataService;
import com.bird.system.service.ISysDictTypeService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.core.io.support.ResourcePatternResolver;
import org.springframework.core.type.classreading.CachingMetadataReaderFactory;
import org.springframework.core.type.classreading.MetadataReader;
import org.springframework.core.type.classreading.MetadataReaderFactory;
import org.springframework.util.ClassUtils;

import java.util.ArrayList;
import java.util.List;

/**
 * Mybatis支持*匹配扫描包
 *
 * @author bird
 */
@Configuration
public class DictEnumLoadConfig implements ApplicationRunner {

	private static final Logger LOG = LoggerFactory.getLogger(DictEnumLoadConfig.class);

	@Value("${bird.enumsTypeHandlePackage}")
	private String enumsTypeHandlePackage;

	@Autowired
	private ISysDictDataService sysDictDataService;

	@Autowired
	private ISysDictTypeService sysDictTypeService;


	@Override
	public void run(ApplicationArguments args) throws Exception {
		refreshEnumDictData();
	}

	/**
	 * 刷新枚举字典
	 */
	public void refreshEnumDictData() {
		LOG.info("刷新枚举字典....");
		List<Class<BaseEnum>> definitionEnum = getAllEnums();
		SysDictDataEntity update = null;
		for (Class<BaseEnum> baseEnumClass : definitionEnum) {
			// 0.基础数据构造
			BaseEnum[] anEnums = baseEnumClass.getEnumConstants();
			EnumDescription annotation = baseEnumClass.getAnnotation(EnumDescription.class);
			String cssClass = annotation.cssClass();
			String listClass = annotation.listClass();
			String remark = annotation.name();
			String select = annotation.select();
			String status = annotation.status();
			String dictType = baseEnumClass.getSimpleName();
			// 1.是否已经添加父类字典
			SysDictTypeQueryParams sysDictDataQueryParams = new SysDictTypeQueryParams();
			sysDictDataQueryParams.setDictType(dictType);
			List<SysDictTypeEntity> sysDictTypes = sysDictTypeService.selectDictTypeList(sysDictDataQueryParams);
			if (sysDictTypes.isEmpty()) {
				SysDictTypeEntity sysDictType = new SysDictTypeEntity();
				sysDictType.setDictName(remark);
				sysDictType.setDictType(dictType);
				sysDictType.setStatus("0");
				sysDictType.setCreateBy("system-mybatis");
				sysDictType.setRemark(remark);
				sysDictTypeService.insertDictType(sysDictType);
			}

			// 2.子类字典数据构建
			for (int dictSort = 1; dictSort < anEnums.length + 1; dictSort++) {
				LOG.info("刷新......");
				String dictValue = anEnums[dictSort - 1].getKey();
				String dictLabel = anEnums[dictSort - 1].getValue();
				update = new SysDictDataEntity();
				update.setCssClass(cssClass);
				update.setDictLabel(dictLabel);
				update.setDictValue(dictValue);
				update.setStatus(status);
				if (dictValue.equals(select)) {
					update.setIsDefault("Y");
				} else {
					update.setIsDefault("N");
				}
				update.setRemark(remark);
				update.setListClass(listClass);
				update.setDictSort((long) dictSort);
				update.setDictType(dictType);
				// 1.查询是否存在
				SysDictDataQueryParams query = new SysDictDataQueryParams();
				query.setDictType(dictType);
				query.setDictValue(dictValue);
				List<SysDictDataEntity> sysDictData = sysDictDataService.selectDictDataList(query);
				if (sysDictData.isEmpty()) {
					// 2新增字典数据
					update.setCreateBy("system-mybatis");
					sysDictDataService.insertDictData(update);
				} else {
					// 3修改字典数据
					update.setUpdateBy("system-mybatis");
					update.setId(sysDictData.get(0).getId());
					sysDictDataService.updateDictData(update);
				}
			}
		}
		LOG.info("刷新枚举字典....完毕");
	}

	/**
	 * 获取配置路径的枚举
	 */
	public List<Class<BaseEnum>> getAllEnums() {
		/**
		 * 存放已经定义BaseEnum的子类容器,初始化字典SQL持久化使用
		 */
		List<Class<BaseEnum>> definitionEnum = new ArrayList<>();
		ResourcePatternResolver resolver = (ResourcePatternResolver) new PathMatchingResourcePatternResolver();
		MetadataReaderFactory metadataReaderFactory = new CachingMetadataReaderFactory(resolver);
		try {
			for (String aliasesPackage : enumsTypeHandlePackage.split(",")) {
				String classPath = ResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX
						+ ClassUtils.convertClassNameToResourcePath(aliasesPackage.trim()) + "/**/*.class";
				Resource[] resources = resolver.getResources(classPath);
				if (resources != null && resources.length > 0) {
					MetadataReader metadataReader = null;
					for (Resource resource : resources) {
						if (resource.isReadable()) {
							metadataReader = metadataReaderFactory.getMetadataReader(resource);
							Class aClass = Class.forName(metadataReader.getClassMetadata().getClassName());
							if (aClass.getInterfaces().length > 0 && aClass.getInterfaces()[0].equals(BaseEnum.class)) {
								Class<BaseEnum> baseEnumClass = (Class<BaseEnum>) aClass;
								definitionEnum.add(baseEnumClass);
							}
						}
					}
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return definitionEnum;
	}

}